﻿#include "ais_light.h"

CAGD::AIS_PointLight::AIS_PointLight(Light light) : AIS_Point(Handle(GeomPoint)(new GeomPoint(light.position)))
{
    m_info.light = light;
    m_info.psize = 16;
}

void CAGD::AIS_PointLight::UpdateInfo()
{
    // 继承模型矩阵
    auto parent = GetParent();
    if (parent != nullptr)
    {
        parent->UpdateInfo();
        m_info.modelMat = parent->GetInfo().modelMat;
    }

    // 注意刷新位置坐标
    m_info.light.position = m_vertex->Geom()->Point();

    // 根据状态设置颜色
    if (m_info.status == AIS_Status::NONE)
    {
        RGB color = m_info.light.diffuse;
        m_info.color = {color.X(), color.Y(), color.Z(), 1};
    }
    else if (m_info.status == AIS_Status::HANG)
        m_info.color = {0, 0, 1, 1};
    else if (m_info.status == AIS_Status::TOUCH)
        m_info.color = {0, 0, 0, 1};
}

CAGD::AIS_Type CAGD::AIS_PointLight::GetType() const
{
    return AIS_Type::POINTLIGHT;
}

CAGD::AIS_DirLight::AIS_DirLight(Light light) : AIS_Point(Handle(GeomPoint)(new GeomPoint(light.position)))
{
    // 设为不可交互
    m_info.light = light;
    m_info.psize = 16;
    m_info.active = false;

    // 创建一个操作杆，以当前点为起点，创建一个新的端点
    auto pole = Handle(AIS_Pole)(
        new AIS_Pole(m_vertex->Geom(), Handle(GeomPoint)(new GeomPoint(light.position + light.direction))));
    AddChild(pole);
    m_context.CreateObject(pole);
}

void CAGD::AIS_DirLight::UpdateInfo()
{
    // 继承模型矩阵
    auto parent = GetParent();
    if (parent != nullptr)
    {
        parent->UpdateInfo();
        m_info.modelMat = parent->GetInfo().modelMat;
    }

    // 注意刷新位置坐标
    auto pole = dynamic_cast<AIS_Pole *>(GetChild(AIS_Type::POLE));
    m_info.light.position = m_vertex->Geom()->Point();
    m_info.light.direction = (pole->GetPoints()[1]->Point() - m_vertex->Geom()->Point()).Normalized();

    if (m_info.status == AIS_Status::NONE)
    {
        RGB color = m_info.light.diffuse;
        m_info.color = {color.X(), color.Y(), color.Z(), 1};
    }
    else
        m_info.color = {0, 0, 0, 1};
}

CAGD::AIS_Type CAGD::AIS_DirLight::GetType() const
{
    return AIS_Type::DIRLIGHT;
}

void CAGD::AIS_DirLight::RecvMessage(Message mess)
{
    // 跳过 AIS_Point 的消息处理，防止 none 消息隐藏底层的操作杆
    AIS_Base::RecvMessage(mess);
}

CAGD::AIS_SpotLight::AIS_SpotLight(Light light) : AIS_Point(Handle(GeomPoint)(new GeomPoint(light.position)))
{
    // 设为不可交互
    m_info.light = light;
    m_info.psize = 16;
    m_info.active = false;

    // 标记外边界
    auto center = Handle(AIS_Pole)(
        new AIS_Pole(m_vertex->Geom(), Handle(GeomPoint)(new GeomPoint(light.position + light.direction))));
    auto outer = Handle(AIS_Pole)(
        new AIS_Pole(m_vertex->Geom(), Handle(GeomPoint)(new GeomPoint(light.position + light.direction / 2))));
    outer->GetInfo().diffuseTex = TEXTURE::SNIPPLE;

    // 创建两个操纵杆
    AddChild(center);
    AddChild(outer);
    m_context.CreateObject(center);
    m_context.CreateObject(outer);
}

void CAGD::AIS_SpotLight::UpdateInfo()
{
    // 继承模型矩阵
    auto parent = GetParent();
    if (parent != nullptr)
    {
        parent->UpdateInfo();
        m_info.modelMat = parent->GetInfo().modelMat;
    }

    // 注意刷新位置坐标
    auto center = dynamic_cast<AIS_Pole *>(GetChild(AIS_Type::POLE, 0));
    auto outer = dynamic_cast<AIS_Pole *>(GetChild(AIS_Type::POLE, 1));
    m_info.light.position = m_vertex->Geom()->Point();
    m_info.light.direction = (center->GetPoints()[1]->Point() - m_vertex->Geom()->Point()).Normalized();
    m_info.light.cutOff =
        acos(m_info.light.direction * (outer->GetPoints()[1]->Point() - m_vertex->Geom()->Point()).Normalized());

    if (m_info.status == AIS_Status::NONE)
    {
        RGB color = m_info.light.diffuse;
        m_info.color = {color.X(), color.Y(), color.Z(), 1};
    }
    else
        m_info.color = {0, 0, 0, 1};
}

CAGD::AIS_Type CAGD::AIS_SpotLight::GetType() const
{
    return AIS_Type::SPOTLIGHT;
}

void CAGD::AIS_SpotLight::RecvMessage(Message mess)
{
    // 跳过 AIS_Point 的消息处理，防止 none 消息隐藏底层的操作杆
    AIS_Base::RecvMessage(mess);
}
